package test00.test06;

/**
 *
 *  模拟 JDK
 * @Author lzp
 * @Date 2024-04-02
 */
public class MyArrayList<E> {

    /**
     *集合大小
     */
    private int size;

    /**
     * 动态数组 ArrayList集合实际是对数组进行封装
     */
    private Object[] eleemtDate;

    /**
     *  默认数组长度
     */
    private static final int DEFAULT_CAPACITY = 3;


    public MyArrayList(){
        eleemtDate = new Object[DEFAULT_CAPACITY];
    }

    /**
     * 重载构造方法 - 用户指定数组的容量
     *
     * @param size
     */
    public MyArrayList(int size){
        eleemtDate = new Object[size];
    }

    /**
     * 添加元素
     * @param e
     * @return
     */
    public boolean add(E e){
        //判断数组容量是否充足
        ensureCapacityInternal();
        this.eleemtDate[size++] = e;
        //size++;
        return true;
    }

    public Object[] getEleemtDate() {
        return this.eleemtDate;
    }

    /**
     * 返回集合元素的实际个数
     * @return
     */
    public int size(){
       return this.size =size;
    }

    /**
     *实现数组动态扩容
     */
    private void ensureCapacityInternal(){
        if (size >= eleemtDate.length){
            //1 动态扩容 - 原来长度 * 2
            Object[] newArr = new Object[eleemtDate.length * 2];

            //2 复制原数组的数据
            System.arraycopy(eleemtDate, 0, newArr, 0, eleemtDate.length);

            eleemtDate = newArr;
        }
    }

    /**
     *获取集合下标对应的元素
     * @param index 下标
     * @return 对应的元素
     */
    public E get(int index){
        //检查下标索引是否越界
        rangeCheck(index);

        return (E) eleemtDate[index];
    }

    /**
     * 检查下标合法性 -- 封装方法
     * 1）复用
     * 2）单一职责原则
     * @param index
     */
    public void rangeCheck(int index){
        if (index < 0 || index >= eleemtDate.length){
            throw new RuntimeException("数组下标越界");
        }
    }

    /**
     *  删除元素
     * @param index
     * @return
     */
    public E remove(int index){
        //1 检查下标索引是否越界
        rangeCheck(index);

        //2 获取删除的元素
        E oldValue = (E) eleemtDate[index];

        // 3.判断删除元素的位置
        int numMoved = size - index -1 ;
        if (numMoved > 0){
            System.arraycopy(eleemtDate, index + 1
                    , eleemtDate, index, numMoved);
        }
        eleemtDate[--size] = null;

        //返回删除的元素
        return oldValue;
    }

    /**
     * 给集合某个下标设置元素
     *
     * @param index
     * @param element
     * @return
     */
    public E set(int index, E element) {
        // 1.检查下标索引是否越界
        rangeCheck(index);

        // 2.获取被覆盖的元素
        E oldValue = (E) eleemtDate[index];

        // 3.覆盖下标索引对应的元素
        eleemtDate[index] = element;

        // 4.返回被覆盖的元素
        return oldValue;
    }

    /**
     * 判断集合是否为空
     *
     * @return
     */
    public boolean isEmpty() {
        return size == 0;
    }
}
